/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MeshlessShapeFunctions;

import java.util.ArrayList;
import java.util.Iterator;

import jmeshless.NewOkCancelDialog;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import FEMShapeFunction1D.FEMShapeFunction1D1;
import HashMatrix2.HashMatrix2;
import HashMatrix2.LUFactorization;
import Integration.IFunction1D;
import Integration.derivavty;

/**
 *
 * @author mark_o
 */
public class JMeshlessInterpolationFunction1DCoupled2 implements IFunction1D {

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



	protected double EPS = 0.0000001;
    protected int PolinomialDegree;
    protected double xii;
    protected double rho;
    protected IKernelFunction func;
    protected HashMatrix2 A;
    protected HashMatrix2 Ax;
    protected double[] b;
    protected ArrayList<Particle> NodeList;
    protected ArrayList<FEMShapeFunction1D1> FEMShapeFunctionList;

    public JMeshlessInterpolationFunction1DCoupled2(int PolinomialDegree, double xii, double rho, IKernelFunction func, ArrayList<FEMShapeFunction1D1> FEMShapeFunctionList) {
        this.PolinomialDegree = PolinomialDegree;
        this.xii = xii;
        this.rho = rho;
        this.func = func;
        this.FEMShapeFunctionList = FEMShapeFunctionList;
    }

    public double getRho() {
        return rho;
    }

    public double getXii() {
        return xii;
    }

    public void setNodeList(ArrayList<Particle> NodeList) {
        this.NodeList = NodeList;
    }

    private double[] calculateFEMAproximation(double x){
        ArrayList<Double> BaseVector = this.getBaseVector(x, xii);
        double[] res = new double[BaseVector.size()];
        double tmp = 0.0;
        for (int i = 0; i < FEMShapeFunctionList.size(); i++) {
            FEMShapeFunction1D1 fEMShapeFunction1D1 = FEMShapeFunctionList.get(i);
//            BaseVector = this.getBaseVector(fEMShapeFunction1D1.getXi(),xii);/////////////////////////////////////
            BaseVector = this.getBaseVector(fEMShapeFunction1D1.getXi(),fEMShapeFunction1D1.getXi());
            tmp = fEMShapeFunction1D1.calculate(x);
            for (int j = 0; j < res.length; j++) {
                res[j]+= BaseVector.get(j)*tmp;
            }
        }
        return res;
    }
    
    private double[] calculateFEMDerivatyAproximation(double x){
        ArrayList<Double> BaseVector = this.getBaseVector(x, xii);
        double[] res = new double[BaseVector.size()];
        double tmp = 0.0;
        for (int i = 0; i < FEMShapeFunctionList.size(); i++) {
            FEMShapeFunction1D1 fEMShapeFunction1D1 = FEMShapeFunctionList.get(i);
//            BaseVector = this.getBaseVector(fEMShapeFunction1D1.getXi(),xii);/////////////////////////////////////
            BaseVector = this.getBaseVector(fEMShapeFunction1D1.getXi(),fEMShapeFunction1D1.getXi());
            tmp = fEMShapeFunction1D1.calculateDerivaty(x);
            for (int j = 0; j < res.length; j++) {
                res[j]+= BaseVector.get(j)*tmp;
            }
        }
        return res;
    }

    public ArrayList<Double> getBaseVector(double x, double xi){
        ArrayList<Double> L = new ArrayList<Double>();
        for (int i = 0; i <= this.PolinomialDegree; i++) {
        	L.add(Math.pow((xi), i));
//        	L.add(Math.pow((x-xi)/rho, i));
//            L.add(Math.pow((xi-x)/rho, i));
        }
        return L;
    }

//    public ArrayList<Double> getBaseVector(double x, double xi){
//        ArrayList<Double> L = new ArrayList<Double>();
//        for (int i = 0; i <= this.PolinomialDegree; i++) {
//            L.add(Math.pow((xi), i));
//        }
//        return L;
//    }

    public ArrayList<Double> getBaseVectorDerivaty(double x, double xi){
        ArrayList<Double> L = new ArrayList<Double>();
        L.add(0.0);
        for (int i = 1; i <= this.PolinomialDegree; i++) {
            L.add(i * Math.pow((xi), i-1));///////////!!!!!!!!!!!!!!!!!!!!!
//            L.add(i/rho * Math.pow((xi-x)/rho, i-1));///////////!!!!!!!!!!!!!!!!!!!!!
        }
        return L;
    }


    public double calculate(double x){
        if((xii-rho>x)||(xii+rho<x)){
            return  0;
        }
        
        ArrayList<Double> BaseVector = getBaseVector(x, xii);
        int n = BaseVector.size();
        b = new double[n];
        A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
        for (int i = 0; i < NodeList.size(); i++) {
            Particle particle = NodeList.get(i);
            calculateAlfa(x,particle);
        }
        BaseVector = getBaseVector(xii, xii);
        boolean key=false;
        double val = func.evaluate((xii-x)/rho);
        
        for (int i = 0; i < b.length; i++) {
            b[i] = BaseVector.get(i)*val;
            if(Math.abs(b[i])>EPS){key = true;}else{b[i]=0.0; }
        }

        double returnValue = 0.0;
        if(key){
            LUFactorization lu = new LUFactorization(A);
            double[] res = lu.calculate(b);

            double[] bFEM = this.calculateFEMAproximation(x);    
            BaseVector = getBaseVector(x, x);
            for (int i = 0; i < b.length; i++) {
                returnValue+=(BaseVector.get(i) - bFEM[i])*res[i];
//            	returnValue+=(BaseVector.get(i))*res[i];
            }
        }
        if (Double.isNaN(returnValue)) {
			returnValue = 0.0;
		}
        return returnValue;
    }


    private void calculateAlfa(double x, Particle xi){
        ArrayList<Double> BaseVector = getBaseVector(x, xi.x);
        int n = BaseVector.size();
        for (int i = 0; i < n; i++) {
            double val = BaseVector.get(i)*func.evaluate((x-xi.x)/xi.rho);
            for (int j = 0; j < n; j++) {
                A.setValue(i, j, A.getValue(i, j)+val*BaseVector.get(j));
            }
        }
    }
    
    private void calculateAlfax(double x, double xi){
        ArrayList<Double> BaseVector = getBaseVector(x, xi);
        int n = BaseVector.size();
        for (int i = 0; i < n; i++) {
            double val = BaseVector.get(i)*func.evaluateDerivaty((xi-x)/rho);
            for (int j = 0; j < n; j++) {
                Ax.setValue(i, j, Ax.getValue(i, j)+val*BaseVector.get(j));
            }
        }
    }

    public double calculateDiffuseDerivaty(double x){
    	if((xii-rho>x)||(xii+rho<x)){
            return  0;
        }
        
        ArrayList<Double> BaseVector = getBaseVector(x, xii);
        int n = BaseVector.size();
        b = new double[n];
        A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
        for (int i = 0; i < NodeList.size(); i++) {
            Particle particle = NodeList.get(i);
            calculateAlfa(x,particle);
        }
        BaseVector = getBaseVector(xii, xii);
        boolean key=false;
        double[] bFEM = this.calculateFEMAproximation(x);
        for (int i = 0; i < b.length; i++) {
            b[i] = BaseVector.get(i) - bFEM[i];
//            if(b[i]!=0.0){key = true;}
            if(Math.abs(b[i])>EPS){key = true;}else{b[i]=0.0; }
        }

        double returnValue = 0.0;
        if(key){
            LUFactorization lu = new LUFactorization(A);
            double[] res = lu.calculate(b);

            double val = func.evaluate((xii-x)/rho);
            BaseVector = getBaseVector(x, x); //TODO check if x / xi which is right 
            for (int i = 0; i < b.length; i++) {
                returnValue+=BaseVector.get(i)*res[i]*val;
            }
        }
        if (Double.isNaN(returnValue)) {
			returnValue = 0.0;
			System.out.println("вийшло нан ....");
		}
        return returnValue;
    }

    public double calculateDerivaty(double x){
    	if((xii-rho>x)||(xii+rho<x)){
            return  0;
        }
        ArrayList<Double> BaseVector = getBaseVector(x, xii);
        int n = BaseVector.size();
        b = new double[n];
        A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
        for (int i = 0; i < NodeList.size(); i++) {
            Particle particle = NodeList.get(i);
            calculateAlfa(x,particle);
        }
        
        double val = func.evaluate((x-xii)/rho);
        BaseVector = getBaseVector(xii, xii);
        boolean key=false;
        for (int i = 0; i < b.length; i++) {
            b[i] = BaseVector.get(i)*val;
            if(Math.abs(b[i])>EPS){key = true;}
        }

        double returnValue = 0.0;
        if(key){
            LUFactorization lu = new LUFactorization(A);
            double[] res = lu.calculate(b);
            
            val = func.evaluateDerivaty((x-xii)/rho);
            key=false;            
            double[] tmp = new double[b.length];
        	for (int j = 0; j < this.NodeList.size(); j++) { // по вузлах
        		Particle xj = NodeList.get(j);
        			val = func.evaluateDerivaty((x-xj.x)/rho);
        			BaseVector = this.getBaseVector(xj.x, xj.x);
        			double tmpVal = 0.0;
        			for (int k = 0; k < res.length; k++) {// альфа на вектор Р і вагу ...
        				tmpVal += BaseVector.get(k)*res[k];
        			}
        			
        			for (int k = 0; k < res.length; k++) {//число на вектор Р 
        				tmp[k]+=BaseVector.get(k)*tmpVal*val;
        			}
			}
        	val = func.evaluateDerivaty((x-xii)/rho);
        	BaseVector = this.getBaseVector(xii, xii);
            for (int i = 0; i < b.length; i++) {
                b[i] = BaseVector.get(i)*val - tmp[i];
                if(Math.abs(b[i])>EPS){key = true;}
            }
            double[] bFEM = this.calculateFEMDerivatyAproximation(x);
        	BaseVector = this.getBaseVectorDerivaty(x, x);
        	for (int j = 0; j < res.length; j++) {
				returnValue+= (BaseVector.get(j) - bFEM[j])*res[j];
			}
            if(key){
            	double[] res2 = lu.calculate(b);
            	
            	BaseVector = this.getBaseVector(x, x);
            	bFEM = this.calculateFEMAproximation(x);
            	for (int j = 0; j < res2.length; j++) {
					returnValue+= (BaseVector.get(j) - bFEM[j])*res2[j];
				}
            }
            
            
        }
//        returnValue-= derivavty.calculate(x, this);
        return derivavty.calculate(x, this);
//        return returnValue;
    }

    public static void main(String[] args){
        ArrayList<FEMShapeFunction1D1> fem = new ArrayList<FEMShapeFunction1D1>();
//        fem.add(new FEMShapeFunction1D1(0.0, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.1, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.2, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.3, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.4, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.5, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.6, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.7, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.8, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.9, 0.1));
//        fem.add(new FEMShapeFunction1D1(1.0, 0.1));
//        fem.add(new FEMShapeFunction1D1(1.0, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.1, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.0, 0.25));
//        fem.add(new FEMShapeFunction1D1(0.25, 0.25));
//        fem.add(new FEMShapeFunction1D1(0.5, 0.25));
//        fem.add(new FEMShapeFunction1D1(0.75, 0.25));
//        fem.add(new FEMShapeFunction1D1(1.0, 0.25));
        
        fem.add(new FEMShapeFunction1D1(0.0, 0.5));
        fem.add(new FEMShapeFunction1D1(0.5, 0.5));
        
        double a = 0.0,b=0.5;
        double x = a;


        int nn = 5;
        ArrayList<Particle> ls1D = new ArrayList<Particle>();
        double h = (b-a)/(double)nn;
        for (int i = 1; i < nn; i++) {
            ls1D.add(new Particle(a+h*i, 0, i));
//            System.out.println(a+h*i);
        }
        
//        double h = 0.1;
//        ls1D.add(new Particle(0.35, 0, 0));
//        ls1D.add(new Particle(0.45, 0, 0));
//        ls1D.add(new Particle(0.55, 0, 0));
//        ls1D.add(new Particle(0.65, 0, 0));
//        ls1D.add(new Particle(0.75, 0, 0));
//        ls1D.add(new Particle(0.85, 0, 0));
//        ls1D.add(new Particle(0.95, 0, 0));
        ArrayList<JMeshlessInterpolationFunction1DCoupled2> ls = new ArrayList<JMeshlessInterpolationFunction1DCoupled2>();
        
//        for (int i = 1; i < ls1D.size()-1; i++) {
        for (int i = 0; i < ls1D.size(); i++) {
//            JMeshlessInterpolationFunction1D f = new JMeshlessInterpolationFunction1D(1, ls1D.get(i).x, 2.6*h, new JGaussian());
        	double rho = 3.1*h;
        	ls1D.get(i).setRho(rho);
            JMeshlessInterpolationFunction1DCoupled2 f = new JMeshlessInterpolationFunction1DCoupled2(2, ls1D.get(i).x, rho, new JGaussian(rho), fem);
            f.setNodeList(ls1D);
            ls.add(f);
        }
        XYSeriesCollection col = new XYSeriesCollection();
        for (Iterator<JMeshlessInterpolationFunction1DCoupled2> iterator = ls.iterator(); iterator.hasNext();) {
			JMeshlessInterpolationFunction1DCoupled2 func = iterator.next();
			x= a;
			XYSeries ser = new XYSeries("func", true,true);
			while (x<b+0.01) {
				ser.add(x,func.calculate(x));
				x+=0.001;
			}
			col.addSeries(ser);
		}
        
        NewOkCancelDialog dialo = new NewOkCancelDialog(null, false, col);
        dialo.setLocationRelativeTo(null);
        dialo.setVisible(true);
        
        
        
        
//        HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, ls.size()+fem.size());
//        double[] B = new double[A.getN()];
//        for (int i = 0; i < ls.size(); i++) {
//            JMeshlessInterpolationFunction1DCoupled2 jMeshlessInterpolationFunction1D = ls.get(i);
//                for (int j = 0; j < ls.size(); j++) {
//                    x = ls1D.get(j).x;
//                    A.setValue(j, i, jMeshlessInterpolationFunction1D.calculate(x));
//                }
//            B[i] = ls1D.get(i).x*ls1D.get(i).x;
////                B[i] = Math.sin(5*ls1D.get(i).x);
//        }
//        
//        for (int i = 0; i <fem.size() ; i++) {
//            FEMShapeFunction1D1 jMeshlessInterpolationFunction1D = fem.get(i);
//                for (int j = 0; j < fem.size(); j++) {
//                    x = fem.get(j).getXi();
//                    A.setValue(j+ls.size(), i+ls.size(), jMeshlessInterpolationFunction1D.calculate(x));
//                }
//            B[i+ls.size()] = fem.get(i).getXi()*fem.get(i).getXi();
////                B[i+ls.size()] = Math.sin(5*fem.get(i).getXi());
//        }
//
//        LUFactorization lu = new LUFactorization(A);
//        double[] res = lu.calculate(B);
//        
//        XYSeries ser = new XYSeries("100", true, true);
//        ser.add(0.0, res[ls.size()]);
//        ser.add(0.1, res[ls.size()+1]);
//        ser.add(0.2, res[ls.size()+2]);
//        ser.add(0.3, res[ls.size()+3]);
//        ser.add(0.4, res[ls.size()+4]);
//        ser.add(0.5, res[ls.size()+5]);
//        x=0.5;
//        while(x<b+0.0001){
//           double tmp2 = 0.0;
//           for (int j = 0; j <ls.size(); j++) {
//               tmp2+= ls.get(j).calculate(x)*res[j];
//           }
//           tmp2+=+ fem.get(5).calculate(x)*res[res.length-1];
//           ser.add(x,tmp2);
//           x+=0.01;
//       }
//        
//        
//        
//        XYSeriesCollection colo  = new XYSeriesCollection(ser);
//        NewOkCancelDialog dialo = new NewOkCancelDialog(null, false, colo);
//        dialo.setLocationRelativeTo(null);
//        dialo.setVisible(true);
//        
//        
//        
//        
//        a = 0.0;
//        
//        
//        
//        for (int i = 0; i < fem.size(); i++) {
//			FEMShapeFunction1D1 f = fem.get(i);
//			x=a;
//            System.out.println("f([");
//            while(x<b+0.001){
//            	double y = f.calculate(x);
//                System.out.println(x+"\t\t"+(y));
//                x+=0.01;
//            }
//            System.out.println("])");
//		}
//        System.out.println();
//        
//        for (int i = 0; i < ls.size(); i++) {
//        	JMeshlessInterpolationFunction1DCoupled2 f = ls.get(i);
//        	x=a;
//            System.out.println("f([");
//            while(x<b+0.001){
//            	double y = f.calculate(x);
//            	//y=derivavty.calculate(x, f);
//                System.out.println(x+"\t\t"+(y));
//                x+=0.01;
//            }
//            System.out.println("])");
//		}
//        System.out.println("==========================================================");
//        
//        
//        XYSeries series1 = new XYSeries("differences", true, true);
//        XYSeries series2 = new XYSeries("full derivaty", true, true);
//        XYSeries series3 = new XYSeries("differences", true, true);
//        XYSeries series4 = new XYSeries("full derivaty", true, true);
//        x=a;
//        JMeshlessInterpolationFunction1DCoupled2 f = ls.get(0);
////        System.out.println("f([");
//        while(x<b+0.001){
//        	double y = f.calculate(x);
////        	y=derivavty.calculate(x, f);
//        	series1.add(x,y);
////            System.out.println(x+"\t\t"+(y));
//            x+=0.01;
//        }
////        System.out.println("])");
//        
//        x=a;
//        JMeshlessInterpolationFunction1DCoupled2 jMeshlessInterpolationFunction1D = ls.get(0);
////        System.out.println("f([");
//        while(x<b+0.001){
//        	double y = jMeshlessInterpolationFunction1D.calculateDerivaty(x);
////        	series2.add(x,y);
////            System.out.println(x+"\t\t"+(y));
//            x+=0.01;
//        }
////        System.out.println("])");
//        x=a;
//        jMeshlessInterpolationFunction1D = ls.get(1);
//        while(x<b+0.001){
//        	double y = jMeshlessInterpolationFunction1D.calculate(x);
//        	
//        	y=derivavty.calculate(x, jMeshlessInterpolationFunction1D);
//        	
//        	series3.add(x,y);
////            System.out.println(x+"\t\t"+(y));
//            x+=0.01;
//        }
//        x=a;
//        jMeshlessInterpolationFunction1D = ls.get(1);
//        while(x<b+0.001){
//        	double y = jMeshlessInterpolationFunction1D.calculateDerivaty(x);
//        	series4.add(x,y);
////            System.out.println(x+"\t\t"+(y));
//            x+=0.01;
//        }
////        System.out.println("])");
////        series1 = null;
//        XYSeriesCollection col  = new XYSeriesCollection(series1);
//        col.addSeries(series2);
////        col.addSeries(series3);
////        col.addSeries(series4);
//        NewOkCancelDialog dialog = new NewOkCancelDialog(null, false, col);
//        dialog.setLocationRelativeTo(null);
//        dialog.setVisible(true);
//        
//
////        for (int i = 0; i < ls.size(); i++) {
////            JMeshlessInterpolationFunction1DCoupled2 f = ls.get(i);
////            x=0.0;
////            if(i!=10){continue;}
////            System.out.println("f([");
////            while(x<b+0.01){
////                System.out.println(x+"\t\t"+f.calculate(x));
////                x+=0.01;
////            }
////            System.out.println("]);");
////            x=0.0;
////            System.out.println("f([");
////            while(x<b+0.01){
////                System.out.println(x+"\t\t"+f.calculateDerivaty(x));
////                x+=0.01;
////            }
////            System.out.println("]);");
////        }
//
//        
//        
//        
////        System.out.println("=====================");
////        GaussQuadrature gau  = new GaussQuadrature(50);
////        final JMeshlessInterpolationFunction1DCoupled2 phi = ls.get(ls.size()-1);
////        final FEMShapeFunction1D1 lFEM = fem.get(0);
////        double res = gau.justGauss(0, 1, new IFunction1D() {
////			
////			@Override
////			public double calculateDerivaty(double x) {
////				// TODO Auto-generated method stub
////				return 0;
////			}
////			
////			@Override
////			public double calculate(double x) {
////				double p1 = phi.calculate(x);
////            	double p1p = phi.calculateDiffuseDerivaty(x);
////            	double p2 = lFEM.calculate(x);
////            	double p2p = lFEM.calculateDerivaty(x);
////            	System.out.println(x+"\t\t"+p2p);
////            	
////                return p1p*p2p;
////			}
////		});
////
////        System.out.println(res);

    }
    
}
///*
// * To change this template, choose Tools | Templates
// * and open the template in the editor.
// */
//
//package MeshlessShapeFunctions;
//
//import FEMShapeFunction1D.FEMShapeFunction1D1;
//import HashMatrix2.HashMatrix2;
//import HashMatrix2.LUFactorization;
//import java.util.ArrayList;
//
///**
// *
// * @author mark_o
// */
//public class JMeshlessInterpolationFunction1DCoupled2 {
//
///*
// * To change this template, choose Tools | Templates
// * and open the template in the editor.
// */
//
//
//
//
//    protected int PolinomialDegree;
//    protected double xii;
//    protected double rho;
//    protected IKernelFunction func;
//    protected HashMatrix2 A;
//    protected double[] b;
//    protected ArrayList<Particle> NodeList;
//    protected ArrayList<FEMShapeFunction1D1> FEMShapeFunctionList;
//
//    public JMeshlessInterpolationFunction1DCoupled2(int PolinomialDegree, double xii, double rho, IKernelFunction func, ArrayList<FEMShapeFunction1D1> FEMShapeFunctionList) {
//        this.PolinomialDegree = PolinomialDegree;
//        this.xii = xii;
//        this.rho = rho;
//        this.func = func;
//        this.FEMShapeFunctionList = FEMShapeFunctionList;
//    }
//
//    public double getRho() {
//        return rho;
//    }
//
//    public double getXii() {
//        return xii;
//    }
//
//    public void setNodeList(ArrayList<Particle> NodeList) {
//        this.NodeList = NodeList;
//    }
//
//    private double[] calculateFEMAproximation(double x){
//        ArrayList<Double> BaseVector = this.getBaseVector(x, xii);
//        double[] res = new double[BaseVector.size()];
//        double tmp = 0.0;
//        for (int i = 0; i < FEMShapeFunctionList.size(); i++) {
//            FEMShapeFunction1D1 fEMShapeFunction1D1 = FEMShapeFunctionList.get(i);
////            BaseVector = this.getBaseVector(fEMShapeFunction1D1.getXi(),xii);/////////////////////////////////////
//            BaseVector = this.getBaseVector(x,fEMShapeFunction1D1.getXi());
//            tmp = fEMShapeFunction1D1.calculate(x);
//            for (int j = 0; j < res.length; j++) {
//                res[j]+= BaseVector.get(j)*tmp;
//            }
//        }
//        return res;
//    }
//
//    public ArrayList<Double> getBaseVector(double x, double xi){
//        ArrayList<Double> L = new ArrayList<Double>();
//        for (int i = 0; i <= this.PolinomialDegree; i++) {
//        	L.add(Math.pow((x-xi)/rho, i));
////            L.add(Math.pow((xi-x)/rho, i));
//        }
//        return L;
//    }
//
////    public ArrayList<Double> getBaseVector(double x, double xi){
////        ArrayList<Double> L = new ArrayList<Double>();
////        for (int i = 0; i <= this.PolinomialDegree; i++) {
////            L.add(Math.pow((xi), i));
////        }
////        return L;
////    }
//
//    public ArrayList<Double> getBaseVectorDerivaty(double x, double xi){
//        ArrayList<Double> L = new ArrayList<Double>();
//        L.add(0.0);
//        for (int i = 1; i <= this.PolinomialDegree; i++) {
//            L.add(i/rho * Math.pow((x-xi)/rho, i-1));///////////!!!!!!!!!!!!!!!!!!!!!
////            L.add(i/rho * Math.pow((xi-x)/rho, i-1));///////////!!!!!!!!!!!!!!!!!!!!!
//        }
//        return L;
//    }
//
//
//    public double calculate(double x){
//        if((xii-rho>x)||(xii+rho<x)){
//            return  0;
//        }
//        ArrayList<Double> BaseVector = getBaseVector(xii, xii);
//        int n = BaseVector.size();
//        b = new double[n];
//        A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
//        for (int i = 0; i < NodeList.size(); i++) {
//            Particle particle = NodeList.get(i);
//            calculateAlfa(x,particle.x);
//        }
//
//        boolean key=false;
//        //BaseVector = getBaseVector(xii, xii);
//        double[] bFEM = this.calculateFEMAproximation(x);/////////////////
//            b[0]=1.0-bFEM[0];
//            if(Math.abs(b[0])>0.0000000001){
//                key = true;
//                for (int i = 1; i < b.length; i++) {
//                    b[i] =(-bFEM[i]);
//                    if(Math.abs(b[i])<0.0000000001){
//                    	b[i]=0.0;
//                    }
//                }
//            }else{
//            	b[0] = 0.0;
//                for (int i = 1; i < b.length; i++) {
//                    b[i] =(-bFEM[i]);
//                    if(Math.abs(b[i])>0.0000000001){
//                    	key = true;
//                    }else{
//                        b[i]=0.0;
//                    }
//                }
//            }
//
//        double returnValue = 0.0;
//        if(key){
//            LUFactorization lu = new LUFactorization(A);
//            double[] res = lu.calculate(b);
//
//            BaseVector = getBaseVector(x, xii);
//            double val = func.evaluate((x-xii)/rho);
//            for (int i = 0; i < b.length; i++) {
//                returnValue+=BaseVector.get(i)*res[i]*val;
//            }
//        }
//        if (Double.isNaN(returnValue)) {
//			returnValue = 0.0;
//		}
//        return returnValue;
//    }
//
//
//    private void calculateAlfa(double x, double xi){
//        ArrayList<Double> BaseVector = getBaseVector(x, xi);
//        int n = BaseVector.size();
//        for (int i = 0; i < n; i++) {
//            double val = BaseVector.get(i)*func.evaluate((x-xi)/rho);
//            for (int j = 0; j < n; j++) {
//                A.setValue(i, j, A.getValue(i, j)+val*BaseVector.get(j));
//            }
//        }
//    }
//
//    public double calculateDiffuseDerivaty(double x){
//        ArrayList<Double> BaseVector = getBaseVector(x, xii);
//        int n = BaseVector.size();
//        b = new double[n];
//        A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
//        for (int i = 0; i < NodeList.size(); i++) {
//            Particle particle = NodeList.get(i);
//            calculateAlfa(x,particle.x);
//        }
//
//        boolean key=false;
//        double[] bFEM = this.calculateFEMAproximation(x);/////////////////
//            
//            b[0]=1-bFEM[0];
//            if(b[0]!=0.0){key = true;}
//        for (int i = 1; i < b.length; i++) {
//            //b[i] =(BaseVector.get(i)*func.evaluate((xii-x)/rho)-bFEM[i]);//////////////////*func.evaluate((xii-x)/rho)
////            b[i] =(BaseVector.get(i)-bFEM[i]);
//            b[i] =  -bFEM[i];
//            if(b[i]!=0.0){key = true;}
//        }
//
//        double returnValue = 0.0;
//        if(key){
//            LUFactorization lu = new LUFactorization(A);
//            double[] res = lu.calculate(b);
//
//            BaseVector = getBaseVectorDerivaty(x, x);
//            double val = func.evaluate((x-xii)/rho);
//            for (int i = 0; i < b.length; i++) {
//                returnValue+=BaseVector.get(i)*res[i]*val;
//            }
//        }
//        if (Double.isNaN(returnValue)) {
//			returnValue = 0.0;
//		}
//        return returnValue;
//    }
//
//    public double calculateDerivaty(double x){
//        ArrayList<Double> BaseVector = getBaseVector(x, xii);
//        int n = BaseVector.size();
//        b = new double[n];
//        A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
//        for (int i = 0; i < NodeList.size(); i++) {
//            Particle particle = NodeList.get(i);
//            calculateAlfa(x,particle.x);
//        }
//
//        boolean key=false;
//        for (int i = 0; i < b.length; i++) {
//            b[i] = BaseVector.get(i)*func.evaluate((x-xii)/rho);
//            if(b[i]!=0.0){key = true;}
//        }
//
//        double returnValue = 0.0;
//        if(key){
//            LUFactorization lu = new LUFactorization(A);
//            double[] res = lu.calculate(b);
//
//            //ArrayList<Double> BaseVector1 = getBaseVectorDerivaty(x, xii);
//            for (int i = 0; i < b.length; i++) {
//                returnValue+=BaseVector.get(i)*res[i]*func.evaluateDerivaty((x-xii)/rho);
//            }
//
//
//            double[] MxAlpha = new double[n];
//            double tmp = 0.0;
//                for (int j = 0; j < BaseVector.size(); j++) {
//                    tmp += BaseVector.get(j)*res[j];
//                }
//            for (int i = 0; i < MxAlpha.length; i++) {
//                MxAlpha[i] = tmp*BaseVector.get(i)*func.evaluateDerivaty((x-xii)/rho);
//            }
//
//            key=false;
//            for (int i = 0; i < b.length; i++) {
//                b[i] -= MxAlpha[i];
//                //b[i] = BaseVector.get(i)*func.evaluatePrime((x-xii)/rho) - MxAlpha[i];
//                if(b[i]!=0.0){key = true;}
//            }
//            if(key){
//                double[] res2 = lu.calculate(b);
//                for (int i = 0; i < b.length; i++) {
//                   returnValue+=BaseVector.get(i)*res2[i]*func.evaluate((x-xii)/rho);
//                }
//            }
//
//
//        }
//        return returnValue;
//    }
//
//    public static void main(String[] args){
//        ArrayList<FEMShapeFunction1D1> fem = new ArrayList<FEMShapeFunction1D1>();
////        fem.add(new FEMShapeFunction1D1(0.0, 1.0));
////        fem.add(new FEMShapeFunction1D1(1.0, 1.0));
////        fem.add(new FEMShapeFunction1D1(0.1, 0.1));
//        fem.add(new FEMShapeFunction1D1(0.0, 0.25));
//        fem.add(new FEMShapeFunction1D1(0.25, 0.25));
//        fem.add(new FEMShapeFunction1D1(0.5, 0.25));
//        fem.add(new FEMShapeFunction1D1(0.75, 0.25));
//        fem.add(new FEMShapeFunction1D1(1.0, 0.25));
//        double a = 0,b=1;
//        double x = a;
//
//
//        int nn = 10;
//        ArrayList<Particle> ls1D = new ArrayList<Particle>();
//        double h = (b-a)/(double)nn;
//        for (int i = 1; i <nn; i++) {
//            ls1D.add(new Particle(a+h*i, 0, i));
//            //System.out.println(a+h*i);
//        }
//        ArrayList<JMeshlessInterpolationFunction1DCoupled2> ls = new ArrayList<JMeshlessInterpolationFunction1DCoupled2>();
//
////        for (int i = 1; i < ls1D.size()-1; i++) {
//        for (int i = 0; i < ls1D.size(); i++) {
////            JMeshlessInterpolationFunction1D f = new JMeshlessInterpolationFunction1D(1, ls1D.get(i).x, 2.6*h, new JGaussian());
//            JMeshlessInterpolationFunction1DCoupled2 f = new JMeshlessInterpolationFunction1DCoupled2(2, ls1D.get(i).x, 2.1*h, new JGaussian(), fem);
//            f.setNodeList(ls1D);
//            ls.add(f);
//        }
//
//
//        for (int i = 0; i < ls.size(); i++) {
//            JMeshlessInterpolationFunction1DCoupled2 f = ls.get(i);
//            x=0.0;
//            System.out.println("f([");
//            while(x<b+0.01){
//                System.out.println(x+"\t\t"+f.calculate(x));
//                x+=0.01;
//            }
//            System.out.println("]);");
//        }
//
//
//
//    }
//    
//}